#include <iostream>
#include <functional>
#include <string>
#include <websocketpp/server.hpp>
#include <websocketpp/config/asio_no_tls.hpp>

typedef websocketpp::server<websocketpp::config::asio> wsserver_t;

//http请求处理 一般返回首页
void http_callback(wsserver_t* wssvr, websocketpp::connection_hdl hdl)
{
    wsserver_t::connection_ptr conn = wssvr->get_con_from_hdl(hdl);
    std::cout << "req_body: " << conn->get_request_body() << std::endl;
    websocketpp::http::parser::request req = conn->get_request();
    std::cout << "method: " << req.get_method() << std::endl;
    std::cout << "uri: " << req.get_uri() << std::endl;

    std::string body = "<html><body><h1>hello world!</h1></body></html>";
    conn->set_body(body);
    conn->append_header("Content-Type", "text/html");
    conn->set_status(websocketpp::http::status_code::ok);
}

//建立websocket连接
void open_callback(wsserver_t* wssvr, websocketpp::connection_hdl hdl)
{
    std::cout << "websocket三次握手成功" << std::endl;
}

//断开websocket连接
void close_callback(wsserver_t* wssvr, websocketpp::connection_hdl hdl)
{
    std::cout << "websocket连接断开" << std::endl;
}

//处理客户端消息并返回响应
void message_callback(wsserver_t* wssvr, websocketpp::connection_hdl hdl, wsserver_t::message_ptr msg)
{
    wsserver_t::connection_ptr conn = wssvr->get_con_from_hdl(hdl);
    std::cout << "wsmsg: " << msg->get_payload() << std::endl;
    std::string res = "client say: " + msg->get_payload();
    conn->send(res, websocketpp::frame::opcode::text);
}

int main()
{
    //1.实例化server对象
     wsserver_t wssvr;

    //2.设置日志等级
    wssvr.set_access_channels(websocketpp::log::alevel::none);

    //3.初始化asio调度器
    wssvr.init_asio();
    wssvr.set_reuse_addr(true);

    //4.设置回调函数
    wssvr.set_http_handler(bind(http_callback, &wssvr, std::placeholders::_1));//这里bind的作用是匹配函数类型
    wssvr.set_open_handler(bind(open_callback, &wssvr, std::placeholders::_1));
    wssvr.set_close_handler(bind(close_callback, &wssvr, std::placeholders::_1));
    wssvr.set_message_handler(bind(message_callback, &wssvr, std::placeholders::_1, std::placeholders::_2));
    
    //5.设置监听端口
    wssvr.listen(8080);

    //6.获取新连接
    wssvr.start_accept();

    //7.启动服务器
    wssvr.run();

    return 0;
}